package team.seekers.hula.common.handler;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import org.apache.commons.lang3.StringUtils;
import team.seekers.hula.common.annotation.HulaJsonFormat;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * @author GH
 * @date 2023/2/5
 */
public class HulaDateFormatAnnotationIntrospector extends JacksonAnnotationIntrospector {

    /**
     * 最大月间隔多少会显示具体时间而不是自定义时间
     */
    private static final int MONTH_DELTA_THRESHOLD = 3;
    /**
     * 超过月间隔使用的日期格式
     */
    private static final String DEFAULT_PATTERN = "yyyy-MM-dd";

    @Override
    public Object findSerializer(Annotated annotated) {
        HulaJsonFormat formatter = annotated.getAnnotation(HulaJsonFormat.class);
        if (formatter != null) {
            return new JsonSerializer<Date>() {
                @Override
                public void serialize(Date d, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                    // 如果pattern有值，则不使用自定义日期格式
                    if (StringUtils.isNotEmpty(formatter.pattern())) {
                        jsonGenerator.writeString(new SimpleDateFormat(formatter.pattern()).format(d));
                        return;
                    }

                    String output = StringUtils.EMPTY;
                    if (d != null) {
                        LocalDateTime date = d.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                        LocalDateTime cur = LocalDateTime.now();
                        int monthDelta = cur.getMonthValue() - date.getMonthValue();
                        if (monthDelta <= MONTH_DELTA_THRESHOLD) {
                            if (monthDelta < 1) {
                                int dayDelta = cur.getDayOfYear() - date.getDayOfYear();
                                if (dayDelta < 1) {
                                    int hourDelta = cur.getHour() - date.getHour();
                                    if (hourDelta < 1) {
                                        int minDelta = cur.getMinute() - date.getMinute();
                                        output = minDelta + "分钟前";
                                    } else {
                                        output = hourDelta + "小时前";
                                    }
                                } else {
                                    output = dayDelta + "天前";
                                }
                            } else {
                                output = monthDelta + "个月前";
                            }
                        } else {
                          output = new SimpleDateFormat(DEFAULT_PATTERN).format(d);
                        }
                    }
                    jsonGenerator.writeString(output);
                }
            };
        }
        return super.findSerializer(annotated);
    }
}
